package com.fly.openapi.service;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.LongStream;

import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.fly.core.utils.SpringContextUtils;

/**
 * TimestampService
 */
@Service
public class TimestampService
{
    /**
     * 批量获取用户timestamp,支持缓存
     */
    @Cacheable(value = "timestamp", key = "#user", unless = "#result.size()==0")
    public List<Long> batchGet(String user)
    {
        String userId = DigestUtils.md5DigestAsHex(user.getBytes(StandardCharsets.UTF_8));
        if (StringUtils.isBlank(userId))
        {
            throw new RuntimeException("用户不存在");
        }
        return LongStream.range(0, 10).map(i -> System.currentTimeMillis() + i).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    }
    
    /**
     * 判断用户timestamp是否有效
     */
    public boolean isFirstUse(String user, Long timestamp)
    {
        // 注意：缓存基于代理实现，直接调用,缓存机制会失效
        TimestampService timestampService = SpringContextUtils.getBean(TimestampService.class);
        List<Long> data = timestampService.batchGet(user);
        boolean isFirstUse = data.contains(timestamp);
        if (isFirstUse)
        {
            timestampService.removeThenUpdate(user, timestamp);
        }
        return isFirstUse;
    }
    
    /**
     * 移除用户已使用的timestamp,刷新缓存
     * 
     */
    @CachePut(value = "timestamp", key = "#user")
    public List<Long> removeThenUpdate(String user, Long timestamp)
    {
        // 注意：缓存基于代理实现，直接调用,缓存机制会失效
        TimestampService timestampService = SpringContextUtils.getBean(TimestampService.class);
        List<Long> data = timestampService.batchGet(user);
        data.remove(timestamp);
        if (data.size() < 5) // 及时补充
        {
            data.addAll(batchGet(user));
        }
        return data;
    }
}